package com.mcxx.modules.minimumliving.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mcxx.common.exception.BizException;
import com.mcxx.constant.DictConstant;
import com.mcxx.modules.minimumliving.service.CalculateService;
import com.mcxx.modules.base.service.read.DictionaryReadService;
import com.mcxx.modules.filemanage.file.service.FileService;
import com.mcxx.modules.miniSalvation.family.entity.FamilyMainEntity;
import com.mcxx.modules.miniSalvation.family.entity.MemberAssetsEntity;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMainReadService;
import com.mcxx.modules.miniSalvation.family.service.read.FamilyMemberReadService;
import com.mcxx.modules.miniSalvation.family.service.read.FamilySupportReadService;
import com.mcxx.modules.miniSalvation.family.service.write.FamilyMainWriteService;
import com.mcxx.modules.miniSalvation.family.service.write.MemberAssetsWriteService;
import com.mcxx.modules.miniSalvation.order.entity.IncomeCalculate;
import com.mcxx.modules.miniSalvation.order.entity.IncomeCert;
import com.mcxx.modules.miniSalvation.order.entity.OrderEntity;
import com.mcxx.modules.miniSalvation.order.service.read.IncomeCalculateReadService;
import com.mcxx.modules.miniSalvation.order.service.read.IncomeCertReadService;
import com.mcxx.modules.miniSalvation.order.service.read.OrderReadService;
import com.mcxx.modules.miniSalvation.order.service.read.StandardReadService;
import com.mcxx.modules.miniSalvation.order.service.write.IncomeCalculateWriteService;
import com.mcxx.modules.miniSalvation.order.service.write.IncomeCertWriteService;
import com.mcxx.util.CommonUtil;
import com.mcxx.util.Constant;
import com.mcxx.util.FailureCode;
import com.yinhai.ta404.core.security.vo.UserAccountVo;
import com.yinhai.ta404.core.service.BaseService;
import com.yinhai.ta404.core.transaction.annotation.TaTransactional;
import com.yinhai.ta404.core.utils.UUIDUtils;
import com.yinhai.yhdcs.core.common.DcsServerException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;


@Slf4j
@Service
@TaTransactional
public class CalculateServiceImpl extends BaseService  implements CalculateService {
    private static final Logger logger = LoggerFactory.getLogger(CalculateServiceImpl.class);
    @Autowired
    private FileService fileService;
    @Autowired
    private IncomeCertWriteService incomeCertWriteService;
    @Autowired
    private IncomeCalculateReadService incomeCalculateReadService;
    @Autowired
    private IncomeCalculateWriteService incomeCalculateWriteService;
    @Autowired
    private FamilyMemberReadService familyMemberReadService;
    @Autowired
    private DictionaryReadService dictionaryReadService;
    @Autowired
    private FamilySupportReadService familySupportReadService;
    @Autowired
    private IncomeCertReadService incomeCertReadService;
    @Autowired
    private FamilyMainWriteService familyMainWriteService;
    @Autowired
    private OrderReadService orderReadService;
    @Autowired
    private StandardReadService standardReadService;
    @Autowired
    private MemberAssetsWriteService memberAssetsWriteService;
    @Autowired
    private FamilyMainReadService familyMainReadService;


    @Override
    public int savCalculate(IncomeCalculate entity,UserAccountVo userAccountVo){
        int count = incomeCalculateReadService.selectCountByOrderId(entity.getOrderId());
        int i = 0;
        if(count>0){

            IncomeCalculate calEntity = new IncomeCalculate();
            calEntity.setOrderId(entity.getOrderId());
            calEntity.setContent(entity.getContent());
            calEntity.setFamilyIncome(entity.getFamilyIncome());
            calEntity.setUpdateTime(new Date());
            i = incomeCalculateWriteService.updateIgnoreNull(calEntity);
        }else{

            String uuid = UUIDUtils.getUUID();
            entity.setId(uuid);
            entity.setCreateTime(new Date());
            i = incomeCalculateWriteService.insertIgnoreNull(entity);
        }

        boolean isExpendHard = savaIncomeAndExpend(entity,userAccountVo);

        FamilyMainEntity familyMainEntity = new FamilyMainEntity();
        familyMainEntity.setId(entity.getFamilyId());
        familyMainEntity.setFamilyRevenue(new BigDecimal(entity.getFamilyIncome()).setScale(2).doubleValue());
        if(isExpendHard){
             familyMainEntity.setIsExpendHard(Constant.IsExpendHard.YES);
        }else{
             familyMainEntity.setIsExpendHard(Constant.IsExpendHard.NO);
        }
        if(!Constant.BusinessCode.DISHOURU.equals(entity.getBusinessType())){
            familyMainWriteService.updateFamily(familyMainEntity);
        }else{
            familyMainWriteService.updateLowerFamily(familyMainEntity);
        }

        return i;
    }

    public boolean savaIncomeAndExpend(IncomeCalculate entity, UserAccountVo userAccountVo){
        String orderId = entity.getOrderId();
        String familyId = entity.getFamilyId();
        boolean isExpendHard = false;

        if(!Constant.BusinessCode.DISHOURU.equals(entity.getBusinessType())){
            memberAssetsWriteService.deleteByOrderId(orderId);
        }else{
            memberAssetsWriteService.deleteByLowerOrderId(orderId);
        }

        String content = entity.getContent();

        JSONObject contentJson = JSONObject.parseObject(content);

        if(contentJson.containsKey("totalSalay")){
            JSONObject totalSalayJson = contentJson.getJSONObject("totalSalay");
            String remark = "";

            if(totalSalayJson.containsKey("oneProjectTotal")){
              String oneProjectTotal = totalSalayJson.getString("oneProjectTotal");
              if(StringUtils.isNotEmpty(oneProjectTotal)){
                  remark += "一事一议事项金额:"+oneProjectTotal+";";
              }
            }
            if(totalSalayJson.containsKey("throughTotal")){
                String throughTotal = totalSalayJson.getString("throughTotal");
                if(StringUtils.isNotEmpty(throughTotal)){
                    remark += "民主评议事项金额:"+throughTotal+"";
                }
            }
            if(StringUtils.isNotEmpty(remark)){
                MemberAssetsEntity assetsEntity = new MemberAssetsEntity();
                assetsEntity.setOrderId(orderId);
                assetsEntity.setFamilyId(familyId);
                assetsEntity.setQuote(0d);
                assetsEntity.setAssetsType(Constant.MemberAssetsType.ZHICHU_BEIZHU);
                assetsEntity.setDescription(remark);
                if(!Constant.BusinessCode.DISHOURU.equals(entity.getBusinessType())){
                    memberAssetsWriteService.insertIgnoreNull(assetsEntity, userAccountVo);
                }else {
                    memberAssetsWriteService.insertLowerAssets(assetsEntity, userAccountVo);
                }
            }
        }



        HashMap<String, String[]> incomeMap = new HashMap<>();


        incomeMap.put("wageSalay",new String[]{Constant.MemberAssetsType.GONG_ZI_XING_SHOU_RU,"wageAmount"});

        incomeMap.put("commercial",new String[]{Constant.MemberAssetsType.JING_YING_XIANG_SHOU_RU,"commercialAmount"});

        incomeMap.put("property",new String[]{Constant.MemberAssetsType.CAI_CHAN_SHOU_RU,"propertyAmount"});

        incomeMap.put("transitivity",new String[]{Constant.MemberAssetsType.ZHUAN_YI_XING_SHOU_RU,"transAmount"});

        incomeMap.put("other1",new String[]{Constant.MemberAssetsType.QI_TA_SHOU_RU,"otherAmount"});
        for(Map.Entry<String, String[]> entry:incomeMap.entrySet()){
            JSONArray salaryArray = contentJson.getJSONObject("data").getJSONArray(entry.getKey());
            if(salaryArray!=null){
                for(int i=0;i<salaryArray.size();i++){
                    JSONObject salaryJson = salaryArray.getJSONObject(i);

                    String jsonKey = entry.getValue()[1];
                    if(salaryJson.containsKey(jsonKey) && StringUtils.isNotBlank(salaryJson.getString(jsonKey))){
                        MemberAssetsEntity assetsEntity = new MemberAssetsEntity();
                        assetsEntity.setOrderId(orderId);
                        assetsEntity.setFamilyId(familyId);
                        assetsEntity.setMemberId(salaryJson.getString("member_id"));
                        assetsEntity.setAssetsType(entry.getValue()[0]);

                        Double quote = Double.valueOf(salaryJson.getString(jsonKey));
                        if(quote != 0){
                            assetsEntity.setQuote(quote);
                            if(!Constant.BusinessCode.DISHOURU.equals(entity.getBusinessType())){
                                memberAssetsWriteService.insertIgnoreNull(assetsEntity, userAccountVo);
                            }else {
                                memberAssetsWriteService.insertLowerAssets(assetsEntity, userAccountVo);
                            }
                        }
                    }
                }
            }
        }

        HashMap<String, String[]> disburseMap = new HashMap<>();

        disburseMap.put("bereftFamily", new String[]{Constant.MemberAssetsType.JIU_YI, "d1"});

        disburseMap.put("disabled",new String[]{Constant.MemberAssetsType.PEI_XUN,"f1"});

        disburseMap.put("education",new String[]{Constant.MemberAssetsType.ZAI_JIU_YE,"r1"});

        disburseMap.put("other2",new String[]{Constant.MemberAssetsType.QI_TA,"g1"});


        for(Map.Entry<String,String[]> entry:disburseMap.entrySet()){
            JSONArray bereftArray = contentJson.getJSONObject("data").getJSONArray(entry.getKey());

            String contentKey = entry.getValue()[1];
            if(!CommonUtil.invalidArgs(bereftArray)){
                for(int i=0;i<bereftArray.size();i++){
                    JSONObject bereftJson = bereftArray.getJSONObject(i);
                    if(bereftJson.containsKey(contentKey)&& StringUtils.isNotBlank(bereftJson.getString(contentKey))){
                        MemberAssetsEntity assetsEntity = new MemberAssetsEntity();
                        assetsEntity.setOrderId(orderId);
                        assetsEntity.setFamilyId(familyId);
                        assetsEntity.setMemberId(bereftJson.getString("member_id"));
                        assetsEntity.setAssetsType(entry.getValue()[0]);
                        Double quote = Double.valueOf(bereftJson.getString(contentKey));
                        if(quote!=0){
                            assetsEntity.setQuote(quote);

                            isExpendHard = true;
                            if(!Constant.BusinessCode.DISHOURU.equals(entity.getBusinessType())){
                                memberAssetsWriteService.insertIgnoreNull(assetsEntity, userAccountVo);
                            }else {
                                memberAssetsWriteService.insertLowerAssets(assetsEntity, userAccountVo);
                            }
                        }
                    }
                }
            }
        }
        return isExpendHard;
    }

    @Override
    public Map<String,Object> getMemberInfoByFamilyId(String familyId,String orderId,String businessType,UserAccountVo userAccountVo){

        List<Map<String,Object>> memberList = null;

        List<Map<String, Object>> supports = null;

        OrderEntity orderEntity = null;
        if(Constant.BusinessCode.DISHOURU.equals(businessType)){
            memberList = familyMemberReadService.queryLowerListToCalculate(familyId);
            supports = familySupportReadService.selectLowerSupportToCalculate(familyId);

            orderEntity = orderReadService.selectLowerOrder(orderId);
            orderEntity.setBusinessInfo(Constant.BusinessCode.DIBAO);
        }else {
            memberList = familyMemberReadService.queryListToCalculate(familyId);
            supports  = familySupportReadService.selectSupportToCalculate(familyId);

            orderEntity = orderReadService.getById(orderId);
        }

        if(CollectionUtils.isNotEmpty(memberList)&&memberList.size()>0){
            for(Map<String,Object> map:memberList){

                map.put("sex",dictionaryReadService.getCodeCache(DictConstant.SEX,String.valueOf(map.get("sex"))).getLabel());

                map.put("is_at_school",dictionaryReadService.getCodeCache(DictConstant.IS_AT_SCHOOL,String.valueOf(map.get("is_at_school"))).getLabel());
                map.put("isSaveObject","1".equals(String.valueOf(map.get("isSaveObject")))?"是":"否");
            }
        }

        if(CollectionUtils.isNotEmpty(supports)&&supports.size()>0){
            supports.forEach(map->map.put("relationStr",dictionaryReadService.getCodeCache(DictConstant.FM_RELATION,String.valueOf(map.get("relationStr"))).getLabel()));
        }

        String areaCode = orderEntity.getCountyCode()+"000000";

        String standMoney = standardReadService.getStandardMoney(areaCode, orderEntity.getBusinessType(), orderEntity.getStandType());
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("memberInfo",memberList);
        resultMap.put("support",supports);
        resultMap.put("standMoney",standMoney);
        resultMap.put("standType",orderEntity.getStandType());
        resultMap.put("userName",userAccountVo.getUsername());
        if(!Constant.BusinessCode.DISHOURU.equals(businessType)){

            String saveType = familyMainReadService.selectSaveTypeByFamilyId(familyId);
            resultMap.put("saveType",saveType);
        }

        return resultMap;
    }


    @Override
    public List<IncomeCert> getCalculateCert(String orderId,String memberId,String fileType){
        List<IncomeCert> certList = incomeCertReadService.selectContentByOrderId(orderId,memberId,fileType);
        if(CollectionUtils.isNotEmpty(certList)&&certList.size()>0){
            certList.forEach(o -> {
                try {
                    String imgUrl = fileService.getFileUrl(o.getImgUrl());
                    o.setImgUrl(imgUrl);
                } catch (DcsServerException e) {
                    o.setImgUrl("#");
                }
            });
        }
       return certList;
    }

    @Override
    public Map<String, Object> uploadCert(MultipartFile file, IncomeCert incomeCert) {

        Map<String, Object> map = new HashMap<>();
        String objectkey = null;
        try {

            logger.info("正在上传证明材料，文件名称：{}",file.getOriginalFilename());
            objectkey = fileService.upload(file.getInputStream(),file.getOriginalFilename());
        } catch (IOException e) {
            logger.error("证明材料上传失败");
            throw new BizException(FailureCode.ERR_20078);
        }
        String certId = IdUtil.simpleUUID();
        incomeCert.setId(certId);
        incomeCert.setImgUrl(objectkey);
        incomeCert.setCreateTime(new Date());
        int i = incomeCertWriteService.insertIgnoreNull(incomeCert);
        if(i>0){
            incomeCert.setImgUrl(fileService.getFileUrl(objectkey));
            map.put("status","1");
            map.put("cert",incomeCert);
        }else{
            map.put("status", "0");
        }
        return map;
    }
}
